using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.UI;
using Microsoft.UI.Text;
using Windows.UI;
using Windows.UI.ViewManagement;
using DevCangjie.utils.Settings;

namespace DevCangjie.utils.Highlight
{
    public class Highlight
    {
        static private bool _highlighting;

        public class HighlightMatch
        {
            public int Start { get; set; }
            public int Length { get; set; }
            public Color Color { get; set; }
            public FormatEffect Bold { get; set; }
            public int Priority { get; set; } // Added Priority
        }

        static public void HighlightSyntax(RichEditTextDocument document, string text)
        {
            if (_highlighting)
            {
                return;
            }
            _highlighting = true;
            try
            {
                // 清除现有格式
                var entireRange = document.GetRange(0, TextConstants.MaxUnitCount);
                Color systemTextColor = GetSystemTextColor();
                entireRange.CharacterFormat.ForegroundColor = systemTextColor;
                entireRange.CharacterFormat.Bold = FormatEffect.Off;

                // 收集所有需要高亮的匹配
                List<HighlightMatch> matches = new List<HighlightMatch>();

                // Sort rules by Priority ascending
                var sortedRules = Settings.Settings.Instance.HighlightRules.OrderBy(r => r.Priority);

                foreach (var rule in sortedRules)
                {
                    if (rule.RuleType == Settings.Settings.HighlightRuleType.LineComment)
                    {
                        // LineComment matching with optional leading whitespace
                        var regex = new Regex(@"//.*$", RegexOptions.Multiline);
                        foreach (Match match in regex.Matches(text))
                        {
                            int start = match.Index;
                            int length = match.Length;

                            matches.Add(new HighlightMatch
                            {
                                Start = start,
                                Length = length,
                                Color = rule.Color,
                                Bold = rule.Bold ? FormatEffect.On : FormatEffect.Off,
                                Priority = rule.Priority // Assign Priority
                            });
                        }
                    }
                    else
                    {
                        // Non-LineComment matching
                        var regex = new Regex(rule.Pattern, RegexOptions.None);
                        foreach (Match match in regex.Matches(text))
                        {
                            matches.Add(new HighlightMatch
                            {
                                Start = match.Index,
                                Length = match.Length,
                                Color = rule.Color,
                                Bold = rule.Bold ? FormatEffect.On : FormatEffect.Off,
                                Priority = rule.Priority // Assign Priority
                            });
                        }
                    }
                }

                // 排序匹配项：先按起始位置，再按优先级（低到高，即高到低优先级）
                var sortedMatches = matches
                    .OrderBy(m => m.Start)
                    .ThenBy(m => m.Priority)
                    .ToList();

                // Track highlighted regions to handle overlaps
                List<(int Start, int End)> highlightedRegions = new List<(int, int)>();

                foreach (var match in sortedMatches)
                {
                    int matchStart = match.Start;
                    int matchEnd = match.Start + match.Length;

                    // Check for overlap with already highlighted regions
                    bool isOverlapping = highlightedRegions.Any(r => matchStart < r.End && matchEnd > r.Start);
                    if (!isOverlapping)
                    {
                        var range = document.GetRange(match.Start, matchEnd);
                        range.CharacterFormat.ForegroundColor = match.Color;
                        range.CharacterFormat.Bold = match.Bold;

                        // Add to highlighted regions
                        highlightedRegions.Add((matchStart, matchEnd));
                    }
                }
            }
            catch (Exception ex)
            {
                // Debug.WriteLine("HighlightSyntax Exception: " + ex.Message);
            }
            finally
            {
                _highlighting = false;
            }
        }

        static private Color GetSystemTextColor()
        {
            UISettings uiSettings = new UISettings();
            return uiSettings.GetColorValue(UIColorType.Foreground);
        }
    }
}